package com.atguigu.gulimall.product.web;

import com.atguigu.gulimall.product.entity.CategoryEntity;
import com.atguigu.gulimall.product.service.CategoryService;
import com.atguigu.gulimall.product.vo.Catalog2VO;
import org.redisson.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 商城首页
 *
 * @author DuGuanghan
 * @since 2024-05-13 10:35:33
 */
@Controller
public class IndexController {
    @Autowired
    private CategoryService categoryService;
    @Autowired
    private RedissonClient redisson;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @RequestMapping({"/", "/index.html"})
    public String index(Model model) {
        // 获取一级分类菜单
        List<CategoryEntity> list = categoryService.getLevel1Catalog();

        model.addAttribute("categorys", list);
        return "index";
    }

    @GetMapping("index/json/catalog.json")
    @ResponseBody
    public Map<String, List<Catalog2VO>> queryCatalog() {
        return categoryService.queryCatalog();
    }

    @GetMapping("/hello")
    @ResponseBody
    public String hello() {
        // 创建一个可重入锁
        RLock lock = redisson.getLock("lock");

        try {
            // 加锁
            lock.lock();
            Thread.sleep(30*1000);
        } catch (Exception e) {

        } finally {
            lock.unlock();
        }

        return "Hello World!";
    }


    @GetMapping("/write")
    @ResponseBody
    public String write() {
        RReadWriteLock anyLock = redisson.getReadWriteLock("anyLock");

        RLock writeLock = anyLock.writeLock();
        String s = "";
        try {
            writeLock.lock();

            s = UUID.randomUUID().toString();

            Thread.sleep(30*1000);
            redisTemplate.opsForValue().set("rwValue", s);
        } catch (InterruptedException e) {

        } finally {
            writeLock.unlock();
        }

        return s;
    }

    @GetMapping("/read")
    @ResponseBody
    public String read() {
        RReadWriteLock anyLock = redisson.getReadWriteLock("anyLock");

        RLock readLock = anyLock.readLock();
        String s = "";
        try {
            readLock.lock();
            Thread.sleep(30*1000);
            s = redisTemplate.opsForValue().get("rwValue");
        } catch (Exception e) {

        } finally {
            readLock.unlock();
        }

        return s;
    }

    @GetMapping("/door")
    @ResponseBody
    public String door() {
        RCountDownLatch countDownLatch = redisson.getCountDownLatch("door-lock");

        countDownLatch.trySetCount(5);
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return "Close the door!!!";
    }

    @GetMapping("/leave")
    @ResponseBody
    public String leave() {
        RCountDownLatch countDownLatch = redisson.getCountDownLatch("door-lock");

        countDownLatch.countDown();

        return "One person leave the room.";
    }

    @GetMapping("/park")
    @ResponseBody
    public String park() throws InterruptedException {
        RSemaphore semaphore = redisson.getSemaphore("park-lock");

        semaphore.acquire();

        return "Add a new one.";
    }

    @GetMapping("/off")
    @ResponseBody
    public String off() throws InterruptedException {
        RSemaphore semaphore = redisson.getSemaphore("park-lock");

        semaphore.release();

        return "Release one.";
    }
}
